package com.capgemini.scaffold.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.capgemini.scaffold.common.BusinessException;
import com.capgemini.scaffold.common.ExceptionEnum;
import com.capgemini.scaffold.dto.LoginFromDTO;
import com.capgemini.scaffold.dto.UserDTO;
import com.capgemini.scaffold.entity.User;
import com.capgemini.scaffold.mapper.UserMapper;
import com.capgemini.scaffold.service.UserService;
import com.capgemini.scaffold.utils.MapCache;
import com.capgemini.scaffold.utils.TokenCache;
import com.capgemini.scaffold.utils.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import static com.capgemini.scaffold.utils.CustomConstant.LOGIN_CODE_KEY;
import static com.capgemini.scaffold.utils.CustomConstant.USER_NAME_PREFIX;


/**
 * @author ShuHao.Wen
 * @since 2022/10/18
 * 登录/注册/个人中心
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private MapCache mapCache;
    @Resource
    private TokenCache tokenCache;
    // 生成token
    String token = LOGIN_CODE_KEY + UUID.randomUUID(true);

    /**
     * 登录功能
     */
    @Override
    public LoginFromDTO login(UserDTO userDTO) {

        // 判断缓存中的用户是否存在
        LoginFromDTO loginFrom = (LoginFromDTO) mapCache.get(userDTO.getAccount());
        User user = new User();
        // 不存在 查询数据库
        if (loginFrom == null) {
            // 根据账号密码查询数据库
            user = userMapper.queryAccount(userDTO.getAccount(), userDTO.getPassword());
            // 用户存在 返回数据
            if (user != null) {
                // userTransitionLoginFromDTO user转loginFromDTO函数
                LoginFromDTO loginFromDTO = userTransitionLoginFromDTO(user);
                // 存入缓存当中
                mapCache.put(loginFromDTO.getAccount(), loginFromDTO);
                // 存入缓存当中
                tokenCache.put(token, loginFromDTO);
                return loginFromDTO;
            } else {
                // 不存在  解决缓存穿透问题  存储null值
                mapCache.put(userDTO.getAccount(), userDTO);
                return loginFrom;
            }

        }
        // 缓存中存在 取出返回
        LoginFromDTO loginFromDTO = (LoginFromDTO) mapCache.get(userDTO.getAccount());
        if (!loginFromDTO.getPassword().equals(userDTO.getPassword()))
            throw new BusinessException(ExceptionEnum.ENTERED_PASSWORDS_DIFFER);
        return loginFromDTO;
    }


    /**
     * 注册功能
     */
    @Override
    @Transactional
    public UserDTO signIn(UserDTO userDTO) {
        // 判断账号是否存在
        if (userMapper.queryCount(userDTO.getAccount()) >= 1)
            throw new BusinessException(ExceptionEnum.DUPLICATE_USER_ACCOUNT);
        //  新增到数据库
        userMapper.insert(userDTOTransitionUser(userDTO));
        return userDTO;
    }

    /**
     * 查询用户信息
     */
    @Override
    public LoginFromDTO queryUserById(Integer id) {

        // 查询用户信息
        User user = userMapper.selectById( UserHolder.getUser().getId());

        // 获取用户信息失败
        if (user == null) throw new BusinessException(ExceptionEnum.FIND_USER_FAIL);

        // 获取用户信息成功
        return userTransitionLoginFromDTO(user);
    }

    /**
     * 修改用户信息
     */
    @Transactional
    @Override
    public User updateUserById(UserDTO userDTO) {
        // 解决缓存一致性问题
        User user = updateUser(userDTO);
        // 先修改数据库
        boolean flag = userMapper.updateUserById(user);
        if (!flag) throw new BusinessException(ExceptionEnum.UPDATE_USER_FAIL);
        // 删除线程存储的用户
        UserHolder.removeUser();
        // 清空缓存
        mapCache.clean();
        tokenCache.clean();
        return user;
    }

    /**
     * 退出登录
     */
    @Override
    public void removeCache() {
        // 删除线程存储的用户
        UserHolder.removeUser();
        // 清空缓存
        mapCache.clean();
        tokenCache.clean();
    }


    //  登录 类型转换 user -> LoginFromDTO
    public LoginFromDTO userTransitionLoginFromDTO(User user) {
        LoginFromDTO loginFromDTO = new LoginFromDTO();
        // id
        loginFromDTO.setId(user.getId());
        // 生成用户名
        loginFromDTO.setName(USER_NAME_PREFIX + RandomUtil.randomString(10));
        // 令牌码
        loginFromDTO.setCode(token);
        // 身份认证
        loginFromDTO.setIdentification(user.getIdentification());
        // 密码
        loginFromDTO.setPassword(user.getPassword());
        // 简介
        loginFromDTO.setIntroduction(user.getIntroduction());
        // 当前用户账号
        loginFromDTO.setAccount(user.getAccount());
        return loginFromDTO;
    }

    // 注册 类型转换 UserDTO -> User
    public User userDTOTransitionUser(UserDTO userDTO) {
        User user = new User();
        user.setAccount(userDTO.getAccount());
        user.setPassword(userDTO.getPassword());
        user.setName(USER_NAME_PREFIX + RandomUtil.randomString(10));
        return user;
    }

    // 修改用户信息
    public User updateUser(UserDTO userDTO) {
        // 判断需要修改的账号是否存在
        if (userMapper.queryCount(userDTO.getAccount()) >= 1)
            throw new BusinessException(ExceptionEnum.UPDATE_USER_ACCOUNT);
        // 获取当前用户id
        Integer userId = UserHolder.getUser().getId();
        User user = new User();
        user.setId(userId);
        user.setAccount(userDTO.getAccount());
        user.setPassword(userDTO.getPassword());
        user.setIntroduction(userDTO.getIntroduction());
        return user;
    }


}
